package com.mars.security.core.validate.code;

import com.mars.security.core.properties.SecurityConstants;
import com.mars.security.core.properties.SecurityProperties;
import com.mars.security.core.validate.code.image.ImageCode;
import com.mars.security.core.validate.code.sms.SmsCodeSender;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.social.connect.web.HttpSessionSessionStrategy;
import org.springframework.social.connect.web.SessionStrategy;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.ServletWebRequest;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * 验证码：
 * 1、图形验证码
 * 2、短信验证码
 * @author MARS
 * @date 2018/7/25
 */

@RestController
public class ValidateCodeController {

    public static final  String SESSION_KEY = "SESSION_KEY_IMAGE_CODE";

    // spring获取session的工具类,使用接口的目的是隔离http协议
    private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();

    // 请求级别的验证码配置
    @Autowired
    private SecurityProperties securityProperties;

    // 引入自定义的图片验证码生成接口
    @Autowired
    private ValidateCodeGenerator imageCodeGenerator;

    // 引入自定义的短信验证码生成接口
    @Autowired
    private ValidateCodeGenerator smsCodeGenerator;

    // 注入自定义的发送器
    @Autowired
    private SmsCodeSender smsCodeSender;

    /**
     * 发送图形验证码
     * @param request
     * @param response
     * @throws IOException
     */
    @GetMapping("/code/image")
    public void createCode(HttpServletRequest request, HttpServletResponse response) throws IOException{

        ImageCode imageCode = (ImageCode)imageCodeGenerator.generate(new ServletWebRequest(request));
        // 存放key-value
        sessionStrategy.setAttribute(new ServletWebRequest(request),SESSION_KEY,imageCode);
        // 输出图片
        ImageIO.write(imageCode.getImage(),"JPEG",response.getOutputStream());
    }

    /**
     * 发送短信验证码
     * @param request
     * @param response
     * @throws IOException
     */
    @GetMapping("/code/sms")
    public void createSms(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletRequestBindingException {

        ValidateCode smsCode = smsCodeGenerator.generate(new ServletWebRequest(request));
        // 存放key-value
        sessionStrategy.setAttribute(new ServletWebRequest(request),SESSION_KEY,smsCode);
        // 获取请求中的参数 ServletRequestUtils.getRequiredStringParameter 表示请求中必须有这个参数
        String mobile = ServletRequestUtils.getRequiredStringParameter(request,"mobile");
        // 连接短信服务商
        smsCodeSender.send(mobile,smsCode.getCode());
    }
    @Autowired
    private ValidateCodeProcessorHolder validateCodeProcessorHolder;

    /**
     * 创建验证码，根据验证码类型不同，调用不同的 {@link ValidateCodeProcessor}接口实现
     *
     * @param request
     * @param response
     * @param type
     * @throws Exception
     */
    @GetMapping(SecurityConstants.DEFAULT_VALIDATE_CODE_URL_PREFIX + "/{type}")
    public void createCode(HttpServletRequest request, HttpServletResponse response, @PathVariable String type)
            throws Exception {
        validateCodeProcessorHolder.findValidateCodeProcessor(type).create(new ServletWebRequest(request, response));
    }

    public static void main(String[] args) {
        // 随机生成6位数字
        Integer length = 8;
        String s = RandomStringUtils.randomNumeric(length);
        System.out.println(s);
    }
}
